﻿namespace Pub.Class
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices;
    using System.Threading;

    public static class IListExtensions
    {
        public static bool BinarySearch<T>(this IList<T> sortedList, T target, out int minIndex) where T: IComparable
        {
            if (target.CompareTo(sortedList[0]) == 0)
            {
                minIndex = 0;
                return true;
            }
            if (target.CompareTo(sortedList[0]) < 0)
            {
                minIndex = -1;
                return false;
            }
            if (target.CompareTo(sortedList[sortedList.Count - 1]) == 0)
            {
                minIndex = sortedList.Count - 1;
                return true;
            }
            if (target.CompareTo(sortedList[sortedList.Count - 1]) > 0)
            {
                minIndex = sortedList.Count - 1;
                return false;
            }
            int num = 0;
            int num2 = sortedList.Count - 1;
            while ((num2 - num) > 1)
            {
                int num3 = (num + num2) / 2;
                if (target.CompareTo(sortedList[num3]) == 0)
                {
                    minIndex = num3;
                    return true;
                }
                if (target.CompareTo(sortedList[num3]) < 0)
                {
                    num2 = num3;
                }
                else
                {
                    num = num3;
                }
            }
            minIndex = num;
            return false;
        }

        public static List<T> GetIntersection<T>(this List<T> list1, List<T> list2) where T: IComparable
        {
            List<T> sortedList = (list1.Count > list2.Count) ? list1 : list2;
            List<T> list3 = (sortedList == list1) ? list2 : list1;
            sortedList.Sort();
            int minIndex = 0;
            List<T> list4 = new List<T>();
            foreach (T local in list3)
            {
                if (sortedList.BinarySearch<T>(local, out minIndex))
                {
                    list4.Add(local);
                }
            }
            return list4;
        }

        public static List<T> GetUnion<T>(this IList<T> list1, IList<T> list2)
        {
            SortedDictionary<T, int> dictionary = new SortedDictionary<T, int>();
            foreach (T local in list1)
            {
                if (!dictionary.ContainsKey(local))
                {
                    dictionary.Add(local, 0);
                }
            }
            foreach (T local2 in list2)
            {
                if (!dictionary.ContainsKey(local2))
                {
                    dictionary.Add(local2, 0);
                }
            }
            return dictionary.Keys.CopyAllToList<T>().ToList<T>();
        }

        public static void InParallel(this List<ThreadStart> tasks)
        {
            tasks.InParallel(0x7fffffff);
        }

        public static void InParallel(this List<ThreadStart> tasks, int maxThreads)
        {
            new ThreadPoolEx().Execute(maxThreads, tasks);
        }

        public static bool IsNullEmpty(this IList self)
        {
            if (!self.IsNull())
            {
                return (self.Count == 0);
            }
            return true;
        }

        public static IList<K> Map<T, K>(this IList<T> list, Func<T, K> function)
        {
            List<K> list2 = new List<K>(list.Count);
            for (int i = 0; i < list.Count; i++)
            {
                list2.Add(function(list[i]));
            }
            return list2;
        }

        public static IList<T> Rand<T>(this IList<T> list)
        {
            return (from p in list
                orderby Guid.NewGuid()
                select p).ToList<T>();
        }

        public static IList<IList<T>> Split<T>(this IList<T> list, int Count)
        {
            List<T> item = new List<T>(Count);
            List<IList<T>> list3 = new List<IList<T>>();
            int num = 0;
            int count = list.Count;
            while (num < count)
            {
                if (item.Count < Count)
                {
                    item.Add(list[num]);
                }
                else
                {
                    list3.Add(item);
                    item = new List<T>(Count) {
                        list[num]
                    };
                }
                num++;
            }
            list3.Add(item);
            return list3;
        }

        public static void Swap<T>(this IList<T> obj, int x, int y)
        {
            if (x != y)
            {
                T local = obj[x];
                obj[x] = obj[y];
                obj[y] = local;
            }
        }
    }
}

